home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
csrc1.arc
/
CALEND.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-07-27
|
10KB
|
304 lines
/*
* C A L E N D A R
*
* Usage:
* calend MM If small, it's a month, if large, a year.
* or
* calend YYYY MM year/month
* or
* calend MM YYYY
*/
#include <stdio.h>
#include <time.h>
#include <define.h>
#define MWIDTH (7*3 + 3) /* Bytes to print a month */
#define WPERMO 6 /* Max. weeks per month */
#define LWIDTH 72 /* Line width */
#define MPERLIN (LWIDTH / MWIDTH) /* Three months per line */
#define WWIDTH (LWIDTH / MPERLIN) /* Bytes in one week */
#define BUFSIZ (WPERMO * LWIDTH) /* Buffer dimension */
char *weekday = " S M Tu W Th F S";
char *monthname[] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
char buffer[BUFSIZ];
main(argc, argv)
int argc;
char *argv[];
{
register int month;
register int year;
register int arg1val;
int arg1len;
int arg2val;
int tvec[2];
struct tm *tm;
time(&tvec[0]);
tm = localtime(&tvec[0]);
year = tm->tm_year + 1900;
month = tm->tm_mon + 1;
if (argc <= 1)
/*
* No arguments mean do last, this, and next month
*/
do3months(year, month);
else {
arg1val = atoi(argv[1]);
arg1len = strlen(argv[1]);
if (argc == 2) {
/*
* Only one argument, if small, it's a month. If
* large, it's a year. Note:
* calend 0082 Year '82
* calend 82 Year 1982
*/
if (arg1len <= 2 && arg1val <= 12)
do3months(year, arg1val);
else {
if (arg1len <= 2 && arg1val > 0 && arg1val <= 99)
arg1val += 1900;
doyear(arg1val);
}
}
else {
/*
* Two arguments, allow 1980 12 or 12 1980
*/
arg2val = atoi(argv[2]);
if (arg1len > 2)
do3months(arg1val, arg2val);
else
do3months(arg2val, arg1val);
}
}
getchar();
getchar();
}
doyear(year)
int year;
/*
* Print a calendar for an entire year.
*/
{
register int month;
register int windex; /* Week index */
if (year < 1 || year > 9999)
usage();
printf("\n\n\n%35d\n\n", year);
for (month = 1; month <= 12; month += MPERLIN) {
printf("%12s%23s%23s\n", monthname[month-1],
monthname[month], monthname[month+1]);
printf("%s %s %s\n", weekday, weekday, weekday);
calendar(year, month+0, &buffer[(MWIDTH-1)*0], LWIDTH);
calendar(year, month+1, &buffer[(MWIDTH-1)*1], LWIDTH);
calendar(year, month+2, &buffer[(MWIDTH-1)*2], LWIDTH);
for (windex = 0; windex < (WPERMO * LWIDTH); windex += LWIDTH)
out(&buffer[windex], LWIDTH);
}
printf("\n\n\n");
}
domonth(year, month)
int year;
int month;
/*
* Do one specific month -- note: no longer used
*/
{
register int windex;
if (year < 1 || year > 9999)
usage();
if (month <= 0 || month > 12)
usage();
printf("%9s%5d\n\n%s\n", monthname[month-1], year, weekday);
calendar(year, month, buffer, WWIDTH);
for (windex = 0; windex < (WPERMO * WWIDTH); windex += WWIDTH)
out(&buffer[windex], WWIDTH);
printf("\n\n");
}
do3months(thisyear, thismonth)
int thisyear;
register int thismonth;
/*
* Do last month, this month, and next months. The parameters
* are guaranteed accurate. (and year will not be less than 2 nor
* greater than 9998).
*/
{
register int windex; /* Week index */
int lastmonth;
int lastyear;
int nextmonth;
int nextyear;
lastyear = nextyear = thisyear;
if ((lastmonth = thismonth - 1) == 0) {
lastmonth = 12;
lastyear--;
}
if ((nextmonth = thismonth + 1) == 13) {
nextmonth = 1;
nextyear++;
}
printf("%9s%5d%18s%5d%18s%5d\n",
monthname[lastmonth - 1], lastyear,
monthname[thismonth - 1], thisyear,
monthname[nextmonth - 1], nextyear);
printf("%s %s %s\n", weekday, weekday, weekday);
calendar(lastyear, lastmonth, &buffer[(MWIDTH-1)*0], LWIDTH);
calendar(thisyear, thismonth, &buffer[(MWIDTH-1)*1], LWIDTH);
calendar(nextyear, nextmonth, &buffer[(MWIDTH-1)*2], LWIDTH);
for (windex = 0; windex < (WPERMO * LWIDTH); windex += LWIDTH)
out(&buffer[windex], LWIDTH);
printf("\n\n\n");
}
out(text, len)
char *text;
int len;
/*
* Clean up and output this line
*/
{
register char *firstp;
register char *lastp;
lastp = &text[len];
for (firstp = text; firstp < lastp; firstp++) {
if (*firstp == EOS)
*firstp = ' ';
}
while (lastp > text && *--lastp == ' ');
lastp[1] = EOS;
printf("%s\n", text);
}
usage()
{
fprintf(stderr, "Calendar parameter error: ");
fprintf(stderr, "Usage: \"calend month\" or \"calend year month\"\n");
fprintf(stderr, "Year and month are integers.\n");
exit(1);
}
/*
* Actually generate a calendar
*/
static char monthdays[] = {
0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
}; /* Thirty days hath september */
/* Except for 1752 */
calendar(year, month, outbuf, offset)
int year;
int month;
char *outbuf; /* Output goes here */
int offset; /* "Distance" to next month */
/*
* Build the calendar for this year/month
*/
{
register char *outp;
register int dow; /* Day of week */
register int day; /* Day in month */
outp = outbuf;
dow = jan1(year);
monthdays[2] = 29; /* Assume leap year */
monthdays[9] = 30; /* Assume no magic */
switch((jan1(year + 1) + 7 - dow) % 7) {
case 2:
/*
* Leap year if jan 1 of next year is two days after
* this year's jan 1
*/
break;
case 1:
/*
* Not a leap year if jan 1 of next year is the next day
* after jan 1 of this year.
*/
monthdays[2] = 28;
break;
default:
/*
* Magic year of 1752 when September lost 11 days.
*/
monthdays[9] = 19;
break;
}
for (day = 1; day < month; day++)
dow += monthdays[day];
dow %= 7; /* Weekday of first of month */
outp += (dow * 3); /* Where to start in calendar */
for (day = 1; day <= monthdays[month]; day++) {
if (day == 3 && monthdays[month] == 19) {
/*
* It's magic (September 3 became September 14)
* And September 1752 really did have 30 days.
*/
day += 11;
monthdays[month] += 11;
}
if (day > 9)
*outp = (day / 10) + '0';
outp++;
*outp++ = (day % 10) + '0';
outp++;
if (++dow >= 7) {
/*
* Sunday, rotate to the next line
*/
dow = 0;
outp = &outbuf[offset];
outbuf = outp;
}
}
}
jan1(year)
register int year;
/*
* Return day that jan 1 falls on for this year.
*/
{
register int day;
/*
* Gregorian calendar: one extra day per four years.
*/
day = year + 4 + (year + 3) / 4;
/*
* Julian calendar: Gregorian less three days per 400
*/
if (year > 1800) {
day -= ((year - 1701) / 100);
day += ((year - 1601) / 400);
}
/*
* Calendar changeover year (valid in America only).
*/
if (year > 1752)
day += 3;
return (day % 7);
}